package com.xy.netty.client;

import com.sun.corba.se.impl.protocol.giopmsgheaders.MessageBase;
import com.xy.netty.client.handler.ClientHandlerInitilizer;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class NettyClient {

    private EventLoopGroup group = new NioEventLoopGroup();

    @Value("${netty.port}")
    private int port;

    @Value("${netty.host}")
    private String host;

    @Autowired
    private ClientHandlerInitilizer clientHandlerInitilizer;

    /**
     * 启动netty服务
     */
    @PostConstruct
    public void start() throws InterruptedException {
        Bootstrap bootstrap = new Bootstrap();
        bootstrap.group(group)
                //指定channel
                .channel(NioSocketChannel.class)
                //指定监听端口
                .remoteAddress(host, port)
                //设置TCP长连接,一般如果两个小时内没有数据的通信时,TCP会自动发送一个活动探测数据报文
                .option(ChannelOption.SO_KEEPALIVE, true)
                //将小的数据包包装成更大的帧进行传送，提高网络的负载,即TCP延迟传输
                .option(ChannelOption.TCP_NODELAY, true)
                .handler(clientHandlerInitilizer);
        ChannelFuture future = bootstrap.connect();
        //客户端重连机制
        future.addListener( (ChannelFutureListener) future1 -> {
            if (future1.isSuccess()) {
                log.info("连接netty服务器成功");
            } else {
                log.info("连接失败，进行重连");
                future1.channel().eventLoop().schedule( () -> {
                    try {
                        start();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }, 20, TimeUnit.SECONDS);
            }
        });
        future.channel().closeFuture().sync();
    }

}
